import { PreTreatmentResult, Scope } from "../../../typings/traverse";
import { getGoalData } from "../../../utils";
import { absolutePath, checkNamespace, preResAttributeLoad } from "../../../utils/traverse";

interface DealGoal {
  $data: Record<string, any>;
}
export function preTreatment(
  goal: DealGoal,
  ele: Element,
  scope?: Scope
): PreTreatmentResult {
  const { $data } = goal;
  let _ele: Element = <Element>ele.cloneNode(true);
  let result: PreTreatmentResult = {
    element: _ele,
    v_for: undefined,
    v_if: undefined,
  };

  if (ele.hasAttribute("v-for") && ele.hasAttribute("v-if")) {
    throw new Error("同一个元素上不允许同时出现v-if，v-for");
  }
  if (ele.hasAttribute("v-for")) {
    let itemPath: string;
    let itemsPath: string;
    // "item in items"
    // 数组中去除 ""
    const v_for: Array<string> = (<string>ele.getAttribute("v-for"))
      .split(" ")
      .filter((val) => {
        if (val.length == 0) {
          return false;
        } else {
          return true;
        }
      });
    let key: string | undefined = undefined;
    if (ele.hasAttribute("v-key")) {
      key = <string>ele.getAttribute("v-key");
    } else if (ele.hasAttribute(":key")) {
      key = <string>ele.getAttribute(":key");
    }
    // v_for[1] == 'in'
    const item = v_for[0],
      items = preResAttributeLoad(v_for[2]);
    itemPath = item;
    itemsPath = items;
    if (scope) {
      if (checkNamespace(itemsPath, scope.item)) {
        itemsPath = absolutePath(scope.items, scope.item, itemsPath);
      }
    }
    /**
     * 获取到了这些指令中的数据后
     * 将深拷贝的元素上的指令删除，下次预处理时，就会当作普通元素对待。
     */
    _ele.removeAttribute("v-for");
    _ele.removeAttribute("v-key");
    _ele.removeAttribute(":key");
    _ele.removeAttribute(":for");
    result.v_for = {
      item: itemPath,
      items: itemsPath,
      length: (<Array<any>>getGoalData($data, itemsPath)).length,
      key,
    };
  } else if (ele.hasAttribute("v-if")) {
    const variate = <string>ele.getAttribute("v-if");
    let path = preResAttributeLoad(variate);
    if (scope) {
      if (checkNamespace(path, scope.item)) {
        path = absolutePath(scope.items, scope.item, path);
      }
    }
    _ele.removeAttribute("v-if");
    result.v_if = {
      path,
    };
  }
  result.element = _ele;
  return result;
}